<?php
class Bitmap
{
	private static $gd_version_number = null;
	private $image;
	private $valid = false;
	private $file;

	function __construct($file, $extension = null)
	{
		$this->file = $file;

		if ($extension == null)
			$extension = substr($file, strrpos($file, '.') + 1);

		$extension = strtoupper($extension);
		
		$this->valid = false;

		switch ($extension)
		{
			case 'JPG':
			case 'JPEG':
				$this->image = @imagecreatefromjpeg($file);
				break;
			case 'GIF':
				$this->image = @imagecreatefromgif($file);
				break;
			case 'PNG':
				$this->image = @imagecreatefrompng($file);
				break;
			case 'BMP':
				$this->image = $this->imagecreatefrombmp($file);
				break;
		}
		
		if ($this->image !== false)
			$this->valid = true;
	}

	function isValid()
	{
		return $this->valid;
	}
	
	function imagecreatefrombmp($p_sFile)
	{
		$file = fopen($p_sFile, "rb");
		$read = fread($file, 10);

		while (!feof($file) && ($read != ""))
			$read .= fread($file, 1024);
		
		$temp = unpack("H*", $read);
		$hex = $temp [1];
		$header = substr($hex, 0, 108);
		
		if (substr($header, 0, 4) == "424d")
		{
			$header_parts = str_split($header, 2);
			$width = hexdec($header_parts[19].$header_parts[18]);
			$height = hexdec($header_parts[23].$header_parts[22]);
			unset ($header_parts);
		}
		
		$x = 0;
		$y = 1;
		
		$image = imagecreatetruecolor($width, $height);
		
		$body = substr($hex, 108);
		
		$body_size = (strlen($body) / 2);
		$header_size = ($width * $height);
		
		$usePadding = ($body_size > ($header_size * 3) + 4);
		
		for($i = 0; $i < $body_size; $i += 3)
		{
			if ($x >= $width)
			{
				if ($usePadding)
					$i += $width % 4;

				$x = 0;
				$y ++;
				if ($y > $height)
					break;
			}
			
			$i_pos = $i * 2;
			$r = hexdec($body[$i_pos + 4].$body[$i_pos + 5]);
			$g = hexdec($body[$i_pos + 2].$body[$i_pos + 3]);
			$b = hexdec($body[$i_pos].$body[$i_pos + 1]);
			
			$color = imagecolorallocate($image, $r, $g, $b);
			imagesetpixel($image, $x, $height - $y, $color);
			
			$x ++;
		}
		
		unset($body);
		
		return $image;
	}

	function save($file)
	{
		$extension = strtoupper(substr($file, strrpos($file, '.') + 1));

		switch ($extension)
		{
			case 'JPG':
			case 'JPEG':
				imagejpeg($this->image, $file);
				break;
			case 'GIF':
				$gif = imagecreatefromgif($this->file);
				$width = imagesx($gif);
				$height = imagesy($gif);
				$width2 = imagesx($this->image);
				$height2 = imagesy($this->image);

				if (($width == $width2) && ($height == $height2))
					copy($this->file, $file);
				else
					imagegif($this->image, $file);

				break;
			case 'PNG':
				imagepng($this->image, $file);
				break;
		}
	}
	
	static function show($file)
	{
		$extension = strtoupper(substr($file, strrpos($file, '.') + 1));

		switch ($extension)
		{
			case 'JPG':
			case 'JPEG':
				header('Content-type: image/jpeg');
				break;
			case 'GIF':
				header('Content-type: image/gif');
				break;
			case 'PNG':
				header('Content-type: image/png');
				break;
			default:
				return;
		}

		readfile($file);
	}
	
	static function gdVersion()
	{
		if (!extension_loaded('gd'))
			return;

		if (Bitmap::$gd_version_number === null)
		{
			ob_start();
			phpinfo(8);
			$info = ob_get_contents();
			ob_end_clean();

			$info = stristr($info, 'gd version');
			preg_match('/\d/', $info, $gd);
			Bitmap::$gd_version_number = $gd[0];
		}
		
		return Bitmap::$gd_version_number;
	}

	function imageCreate($width, $height)
	{
		if (Bitmap::gdVersion() >= 2)
		{
			$image_p = @imagecreatetruecolor($width, $height);
			imagealphablending($image_p, false);
			imagesavealpha($image_p, true);
			return $image_p;
		}
	
		return $image_p = @imagecreate($width, $height);
	}
	
	function resizeGd($image_p, $image, $Xdst, $Ydst, $Xorg, $Yorg, $ancho_dst, $alto_dst, $ancho_org, $alto_org)
	{
		if (Bitmap::gdVersion() >= 2)
			@imagecopyresampled($image_p, $image, $Xdst, $Ydst, $Xorg, $Yorg, $ancho_dst, $alto_dst, $ancho_org, $alto_org);
		else
			@imagecopyresized($image_p, $image, $Xdst, $Ydst, $Xorg, $Yorg, $ancho_dst, $alto_dst, $ancho_org, $alto_org);
	}
	
	private function resize1($x, $y)
	{
		$width = imagesx($this->image);
		$height = imagesy($this->image);
		$ancho = imagesx($this->image);
		$alto = imagesy($this->image);
		
		if ($ancho > $x)
		{
			$width = $x;
			$height = (($alto * $x) / $ancho);
		}
	
		if ($y!=0)
		{
			if ($height > $y)
			{
				$height = $y;
				$width = (($ancho * $y) / $alto);
			}
		}

		$image_p = $this->imageCreate($width, $height);
		$this->resizeGd($image_p, $this->image, 0, 0, 0, 0, $width, $height, $ancho, $alto);
	
		$this->image = $image_p;
	}
	
	private function resize2($x, $y)
	{
		$width = ImageSX($this->image);
		$height = ImageSY($this->image);
	
		$prop = $x / $y;
		if (($width / $height) < $prop)
		{
			// redimensiono en ancho
			$ancho = $x;
			$alto = $height / ($width / $ancho);
		}
		else
		{
			// redimensiono en alto
			$alto = $y;
			$ancho = $width / ($height / $alto);
		}
	
		$image_p = $this->imageCreate($x, $y);
		$this->resizeGd($image_p, $this->image, ($x - $ancho) / 2, ($y - $alto) / 2, 0, 0, $ancho, $alto, $width, $height);
	
		$this->image = $image_p;
	}
	
	function resize($width, $height, $exactSize)
	{
		if ($exactSize)
			$this->resize2($width, $height);
		else
			$this->resize1($width, $height);
	}
}
?>